﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using System.Diagnostics;


namespace SharePointSiteConfigurator
{
#if (!SP2010)
    public sealed class TraceLogger
    {
        #region properties

        private static TraceLogger _Instance = null;
        private static readonly object _Lock = new object();
        private static TraceSource trs = new TraceSource("SiteConfigurator", SourceLevels.Verbose);

        public const string DefaultLogFile = "SiteConfigurator_Trace_Log";
        private const string LogExtention = ".log";

        #endregion

        private TraceLogger()
        {
            SPSecurity.RunWithElevatedPrivileges(
            delegate()
            {
                TextWriterTraceListener tracerCLS = new TextWriterTraceListener(this.GetCurrentLogFile("SiteConfigurator_Trace_Log"));
                trs.Listeners.Add(tracerCLS);
            }
            );
        }

        /// <summary>
        /// Use this instance to enable logging 
        /// </summary>
        public static TraceLogger Instance
        {
            get
            {
                lock (_Lock)
                {
                    if (_Instance == null)
                        _Instance = new TraceLogger();

                    return _Instance;
                }
            }
        }




        /// <summary>
        /// Set log level of tracing
        /// </summary>
        public SourceLevels SetTraceLevel
        {
            get { return trs.Switch.Level; }
            set { trs.Switch.Level = value; }
        }




        #region Public Trace Methods

   

        /// <summary>
        /// Logs exceptions to a seperate logfile in \12\Logs
        /// Uses the Diagnostics.Logging class in this project
        /// </summary>
        /// <param name="message"></param>
        /// <param name="ex"></param>
        /// <param name="categoryName"></param>
        public void TraceError(string message, Exception ex)
        {
            if (trs.Switch.Level >= SourceLevels.Error)
            {
                trs.TraceEvent(TraceEventType.Error, 0, string.Format("{0:yyyy-MM-dd HH:mm:ss} : {1}", DateTime.Now, message));
                trs.TraceEvent(TraceEventType.Error, 0, ex.ToString());
                trs.Flush();
            }
        }

    
        /// <summary>
        /// Logs verbose messages to the seperate log file in \12\logs
        /// </summary>
        /// <param name="message"></param>
        /// <param name="categoryName"></param>
        public void TraceVerboseMessage(string message)
        {
            if (trs.Switch.Level >= SourceLevels.Verbose)
            {
                trs.TraceInformation(string.Format("{0:yyyy-MM-dd HH:mm:ss} : {1}", DateTime.Now, message));
                trs.Flush();
            }
        }
        #endregion


        #region Helper Methods

        /// <summary>
        /// Parse/handle/cleanup the logfiles for the baselogname <c>logfile</c>
        /// </summary>
        /// <param name="logfile">the basename for the logfiles</param>
        /// <returns>the actual filename to log to</returns>
        private string GetCurrentLogFile(string logfile)
        {
            string timestamp = DateTime.Now.AddMinutes(-SPDiagnosticsService.Local.LogCutInterval).ToString("yyyyMMdd-HHmm", CultureInfo.InvariantCulture);


            string lastallowedlogfilename = System.IO.Path.Combine(
                SPDiagnosticsService.Local.LogLocation,
                 logfile + "-" + timestamp + TraceLogger.LogExtention);
            // get existing logfiles
            string[] files = System.IO.Directory.GetFiles(SPDiagnosticsService.Local.LogLocation, logfile + "*.log", System.IO.SearchOption.TopDirectoryOnly);

            System.Collections.ArrayList list = new System.Collections.ArrayList();
            list.AddRange(files);

            // clean up old log files
            if (list.Count > SPDiagnosticsService.Local.LogsToKeep)
            {
                int count = list.Count;
                while (count > SPDiagnosticsService.Local.LogsToKeep)
                {
                    System.IO.File.Delete(list[0] as string);
                    count--;
                }
            }
            // lookup current logfile
            string currentLogFile = string.Empty;
            if (list.Count > 0)
            {
                string lastfile = list[list.Count - 1] as string;
                if (string.Compare(lastfile, lastallowedlogfilename, StringComparison.OrdinalIgnoreCase) > 0)
                    currentLogFile = lastfile;
            }
            // create a new logfile
            if (string.IsNullOrEmpty(currentLogFile))
            {
                string timestampn = DateTime.Now.ToString("yyyyMMdd-HHmm", CultureInfo.InvariantCulture);
                currentLogFile = System.IO.Path.Combine(
                    SPDiagnosticsService.Local.LogLocation,
                     logfile + "-" + timestampn + TraceLogger.LogExtention);
            }
            return currentLogFile;
        }


        #endregion

    }
#endif 
}

